home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / misc / GetOpt_1_3.lha / getopt.DOC < prev    next >
Encoding:
Text File  |  1993-01-25  |  10.3 KB  |  377 lines

  1. getopt.c:    An implementation of the UNIX getopt() C function.
  2.  
  3. Author:        Daniel J. Barrett, barrett@cs.umass.edu
  4. Status:        Public domain
  5.  
  6.  
  7. WHAT IS GETOPT?
  8. ===============
  9.  
  10.     This is an implementation of the standard UNIX getopt() function.
  11. If you already know how to use it, you can ignore the rest of this file,
  12. because my implementation acts just like the UNIX getopt().
  13.  
  14.     Your program must #include "getopt.h" and link with getopt.o.
  15. Have fun!
  16.  
  17.     The rest of this file will teach you about getopt().  It is a
  18. function for C programmers.  If you don't program in C, you can ignore
  19. this whole package, go home, and do something fun instead. :-)
  20.  
  21.  
  22. THE BASICS
  23. ==========
  24.  
  25.     getopt() is a function that makes it MUCH easier for a C program
  26. to process UNIX-like command-line options.  A command-line option in UNIX
  27. is a single letter preceded by a dash, like this:
  28.  
  29.             -x
  30.  
  31.     A flexible program will let the user give options in any order,
  32. separately, grouped together, etc.  However, all this can be a pain for the
  33. programmer.  getopt() removes the pain.
  34.  
  35.  
  36. TERMINOLOGY
  37. ===========
  38.  
  39.     An OPTION appears on the command line and always begins with a dash.
  40.  
  41.     An ARGUMENT appears on the command line but is not an option.
  42. Arguments appear AFTER all of the options.  If you have used UNIX before,
  43. you already know this... at least intuitively.
  44.  
  45.  
  46. A SIMPLE EXAMPLE OF USING GETOPT
  47. ================================
  48.  
  49.     Here is a simple example.  Suppose you have a program called
  50. MyProgram which permits the options -a, -e, and -k.  Also, it permits
  51. the option "-o" which MUST be followed by an output filename.
  52. Your main program will look something like this:
  53.  
  54.     main(int argc, char *argv[])
  55.     {
  56.         int c;
  57.         char filename[BUFSIZ];
  58.  
  59.         while ((c = getopt(argc, argv, "aeko:")) != EOF)
  60.         {
  61.             switch (c)
  62.             {
  63.                 case 'a':
  64.                     puts("I found the 'a' option.");
  65.                     DoSomething();
  66.                     break;
  67.                 case 'e':
  68.                     puts("I found the 'e' option.");
  69.                     DoSomethingElse();
  70.                     break
  71.                 case 'k':
  72.                     puts("I found the 'k' option.");
  73.                     DoAnotherThing();
  74.                     break;
  75.                 case 'o':
  76.                     puts("I found the 'o' option.");
  77.                     puts("It's followed by an argument.");
  78.                     strcpy(filename, optarg);
  79.                     break;
  80.                 case '?':
  81.                 default:
  82.                     puts("ERROR!");
  83.                     break;
  84.             }
  85.         }
  86.     }
  87.  
  88.  
  89. On each iteration of the "while" loop, getopt() is executed, returning
  90. the NEXT command-line option's letter.  When there are no more options,
  91. getopt() returns EOF.
  92.  
  93.     When a program uses getopt(), it allows the user to specify
  94. his/her options in any order, in any grouping.  For example, the following
  95. invocations of the above program (suppose it is called "blammo") are
  96. all equivalent:
  97.  
  98.         1>  blammo -a -o myfile
  99.         1>  blammo -a -omyfile
  100.         1>  blammo -aek -o myfile
  101.         1>  blammo -aek -omyfile
  102.         1>  blammo -eo myfile -ka
  103.         1>  blammo -eomyfile  -ka
  104.  
  105. Your program remains ignorant of the actual order and structure of the
  106. options -- getopt() handles all of this for you transparently.
  107.  
  108.  
  109. HOW A PROGRAMMER USES GETOPT
  110. ============================
  111.  
  112.     In order to use the getopt() function, follow these directions.
  113. Suppose you will be calling getopt() from inside main() in the file main.c.
  114. (This is just an example.)
  115.  
  116. (1)    At the top of main.c, include the mandatory header file:
  117.  
  118.         #include "getopt.h"
  119.  
  120.     This gives your program access to 4 important global variables:
  121.  
  122.         extern char    *optarg;
  123.         extern int    optopt;
  124.         extern int    optind;
  125.         extern int    opterr;
  126.  
  127.     which are described later.
  128.  
  129. (2)    Create an option string:  the third argument of getopt().
  130.     There are two kinds of options:
  131.  
  132.     (a)    Options that may appear alone.
  133.         Examples:  -a, -e, -k, in the above example.
  134.  
  135.     (b)    Options that MUST be followed by a string.
  136.         Example:  Suppose the "-o" option must be followed by a
  137.         filename.  getopt() will enforce this fact.
  138.  
  139.     To create the option string, just make a single string with the
  140.     option letters in any order.  If an option must be followed by
  141.     an string on the command line (as in the "-o" example), follow
  142.     it IMMEDIATELY with a colon (':') in the option string.
  143.  
  144.     An option string that permits the -a, -e, and -k options, plus
  145.     the "-o filename" option, would be:
  146.  
  147.             "aeko:"
  148.  
  149.     Order does not matter; any of the following would work too:
  150.  
  151.             "ao:ke"
  152.             "o:eak"
  153.             "eko:a"
  154.  
  155.     It is slightly more efficient to put the most commonly used options
  156.     earlier in the string, but the speedup is almost unnoticeable.
  157.  
  158. (3)    If you do not want getopt() to print diagnostic messages, set the
  159.     value of the global variable "opterr" to 0 in main()
  160.  
  161.         main(int argc, char *argv[])
  162.         {
  163.             ...
  164.             opterr = 0;
  165.             ...
  166.         }
  167.  
  168.     before calling getopt().
  169.  
  170. (4)    Create your option-processing loop, as in the example at the top
  171.     of this file.
  172.  
  173.  
  174. THE BEHAVIOR OF GETOPT
  175. ======================
  176.  
  177.     The function prototype for getopt() is:
  178.  
  179.         int getopt(int argc, char *argv[], char *optionString);
  180.  
  181. where
  182.  
  183.         argc        The first argument of main().
  184.         argv        The second argument of main().
  185.         optionString    The option string you created in step
  186.                 (2) of the previous section.
  187.  
  188.     getopt() returns one of three values:
  189.  
  190.     (1)    If it reads a LEGAL option, it returns the option's
  191.         character.
  192.  
  193.         If the legal option must be followed by a string, and THE
  194.         STRING IS PRESENT, it returns the option's character.
  195.  
  196.     (2)    If it reads an ILLEGAL option, it returns '?'.
  197.  
  198.         If it reads a legal option which must be followed by a
  199.         string, but THE STRING IS MISSING, it returns '?' also.
  200.  
  201.         The option letter is now found in the global variable optopt.
  202.  
  203.     (3)    If there are no more options, it returns EOF.
  204.         If it encounters the special option "--", it returns EOF.
  205.  
  206.  
  207.  
  208. THE GLOBAL VARIABLES
  209. ====================
  210.  
  211.     When you #include "getopt.h", you get access to 4 important
  212. global variables.
  213.  
  214.         extern char    *optarg;
  215.         extern int    optopt;
  216.         extern int    optind;
  217.         extern int    opterr;
  218.  
  219. These are documented carefully in getopt.h.
  220.  
  221.  
  222. HOW A USER USES GETOPT
  223. ======================
  224.  
  225.     The user may give the command-line options in any order:
  226.  
  227.         1>  blammo -a -e -k
  228.         1>  blammo -k -a -e
  229.         1>  blammo -e -k -a
  230.         etc...
  231.  
  232. or any grouping
  233.  
  234.         1>  blammo -aek
  235.         1>  blammo -ek -a
  236.         1>  blammo -k -ea
  237.  
  238. If an option (like "-o") MUST be followed by a string (like "myfile"), the
  239. user may put the string immediately after the option:
  240.  
  241.         1>  blammo -omyfile
  242.  
  243. or separated by whitespace:
  244.  
  245.         1>  blammo -o myfile
  246.         1>  blammo -o             myfile
  247.  
  248.     All options must precede all arguments.  The following examples
  249. are WRONG:
  250.  
  251.         1>  blammo anything -a -e -k        /* WRONG!!! */
  252.         1>  blammo -o myfile anything -e    /* WRONG!!! */
  253.  
  254. because the argument "anything" appears before options.  In the first
  255. example, getopt() will see no options and return EOF, with optind == 1.
  256. In the second example, getopt() will find the "-o" option and its
  257. string "myfile", and then return EOF with optind==3.  It will not see the
  258. "-e" option.
  259.  
  260.     The special option "--" means "there are no more options."  It
  261. is useful when an argument must begin with a dash, but you don't want
  262. getopt() to process it.  When getopt() reads "--", it returns EOF
  263. immediately, with optind containing the index of the first argument
  264. after the "--".
  265.  
  266.         1>  blammo -e -- -x -y
  267.  
  268. In this example, getopt() finds the "-e" option (and returns 'e'),
  269. then sees "--", and returns EOF.  optind is now 3, with argv[optind] == "-x".
  270.  
  271.  
  272. FACTS ABOUT GETOPT
  273. ==================
  274.  
  275. (1)    When getopt() encounters a legal option, it returns the option
  276.     character.  For example, on encountering the "-e" option, getopt()
  277.     returns 'e'.
  278.  
  279. (2)    When getopt() encounters an illegal option (not given in the
  280.     option string, or missing its following string), it returns
  281.     the character '?'.  The true option character is found in the
  282.     global variable optopt.
  283.  
  284. (3)    When there are no more options, getopt() returns EOF.
  285.  
  286. (4)    getopt() has no other return values but the three given above:
  287.     a character from the option string, a '?' character, or EOF.
  288.  
  289. (5)    The special option "--" (two dashes) means "end of options."
  290.     When getopt() encounters "--", getopt() returns EOF.
  291.  
  292.     This is useful if some of your arguments must begin with dashes.
  293.     For example, in our above example, suppose we want to follow our
  294.     options with the argument "-MyArg".  If we type:
  295.  
  296.             1>  blammo -MyArg
  297.  
  298.     then getopt() will interpret the 'M' (and possibly the remaining
  299.     characters) as options, and print error messages.  But if we type:
  300.  
  301.             1> blammo -- -MyArg
  302.  
  303.     then getopt() quits processing, and argv[optind] == "-MyArg" as
  304.     we wanted.
  305.  
  306. (6)    After getopt() returns EOF, the next argument your program
  307.     should process is argv[optind].
  308.  
  309.     A typical loop for processing the rest of the argument might be:
  310.  
  311.         for (i=optind; i<argc; i++)
  312.             Process(argv[i]);
  313.  
  314.     If optind > argc-1, then there are no more arguments to process.
  315.  
  316. (7)    optarg changes its value on every call of getopt().
  317.     Thus, the following is a BUG:
  318.  
  319.         char *filename;
  320.         filename = optarg;
  321.         getopt(argc, argv, "aejo:");
  322.         printf("The filename is %s\n", filename);
  323.  
  324.     After the call to getopt(), filename is not guaranteed to point at
  325.     anything meaningful.  If you want to save the value of optarg,
  326.     copy it into a private string buffer; for example,
  327.  
  328.         char filename[BIG_ENOUGH_SIZE];
  329.         strcpy(filename, optarg);
  330.  
  331. (8)    getopt() iterates through the options ONLY ONCE.
  332.  
  333.     After getopt() returns EOF, it is useless to you.  You should NOT
  334.     call it again before the program exits.
  335.  
  336. (9)    NEVER change the values of optind, optopt, and optarg.
  337.  
  338.     These variables should be treated as READ-ONLY.
  339.     However, it is OK to set the value of opterr.
  340.  
  341. (10)    While getopt() is actively being used, DO NOT modify argc and
  342.     argv.
  343.  
  344. (11)    The names getopt, optind, optarg, optopt, and opterr are historical.
  345.     They are the same in (I hope) all implementations of getopt().
  346.     You should not change them if you want your code to be portable.
  347.  
  348. (12)    Options are CASE SENSITIVE.
  349.  
  350.     The options "-a" and "-A" are different.
  351.  
  352. (13)    The option "-:" (dash colon) is illegal.  Your program should
  353.     never require this option.
  354.  
  355.  
  356. AN EXAMPLE OF USING GETOPT
  357. ==========================
  358.  
  359.     A complete getopt() example is found in example.c.
  360.     
  361.     Another example is found in getopt.c.  The main() function is
  362. commented out using the preprocessor macro TESTME.  Use your compiler to
  363. #define TESTME, and compile/link getopt.c to create an executable test
  364. program.
  365.  
  366.  
  367. A NOTE FOR MANX AZTEC C USERS
  368. =============================
  369.  
  370.     The enclosed Makefile will create link libraries for you.
  371.  
  372.     If you link with one of these libraries (say, getopt.lib),
  373. you MUST specify "-lgetopt" before "-lc".
  374.  
  375.         1>  ln myfile.o -lc -lgetopt    /* WRONG!!! */
  376.         1>  ln myfile.o -lgetopt -lc    /* CORRECT. */
  377.